package com.alm.handle.service.impl;

import com.alm.common.core.domain.AjaxResult;
import com.alm.common.core.domain.entity.SysDept;
import com.alm.common.core.redis.RedisCache;
import com.alm.common.enums.ChangeModeEnum;
import com.alm.common.enums.YesNotEnum;
import com.alm.common.exception.ServiceException;
import com.alm.entity.DevLogin;
import com.alm.entity.PasingByteModel;
import com.alm.handle.core.domain.entity.*;
import com.alm.handle.core.domain.entity.rq.EditIsTopRQ;
import com.alm.handle.core.domain.entity.rq.GetWayInfoRq;
import com.alm.handle.core.domain.entity.rq.ModeChangeRq;
import com.alm.handle.core.domain.entity.rq.SysDevInfoDevRq;
import com.alm.handle.core.domain.entity.rs.DevInfoPageRs;
import com.alm.handle.core.domain.entity.vo.DevOnlineMacVO;
import com.alm.handle.mapper.*;
import com.alm.handle.service.ISysAreaInfoService;
import com.alm.handle.service.ISysDevCurrentDataService;
import com.alm.handle.service.ISysDevInfoService;
import com.alm.handle.service.SocketDataPasing;
import com.alm.handle.util.ByteUtils;
import com.alm.handle.util.SendMessage;
import com.alm.handle.util.SoketEleKey;
import com.alm.system.service.ISysDeptService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.alm.common.utils.PageUtils.startPage;

@Service
public class SysDevInfoServiceImpl implements ISysDevInfoService {

    @Autowired
    private RedisCache redisCache;
    @Resource
    private SysDevInfoMapper sysDevInfoMapper;

    @Autowired
    private ISysDeptService sysDeptService;

    @Resource
    private SysDevModelMapper sysDevModelMapper;

    @Resource
    private SysAreaInfoMapper sysAreaInfoMapper;

    @Autowired
    private SysDevCurrentDataMapper sysDevCurrentDataMapper;
    @Autowired
    private ISysAreaInfoService areaInfoService;

    @Resource
    private SysDevCommandMapper devCommandMapper;

    @Override
    public List<DevInfoPageRs> selectDevInfoList(SysDevInfoDevRq rq) {
        QueryWrapper queryWrapper=new QueryWrapper();
        if (rq.getRegionId() != null && rq.getRegionId().length()> 1) {
            queryWrapper.eq("menu_id", rq.getRegionId());
            SysAreaInfo sysAreaInfo = sysAreaInfoMapper.selectOne(queryWrapper);
            if (sysAreaInfo != null ) {
                areaInfoService.findAllChild(sysAreaInfo);
            }
            sysAreaInfo.setChildIds(rq.getRegionId());
            rq.setRegionId(sysAreaInfo.getChildIds());
        }else{
            rq.setRegionId(null);
        }
        // 查询所有设备数据
        startPage();
        List<DevInfoPageRs> devInfoList = sysDevInfoMapper.selectDevInfoList(rq);
        devInfoList.forEach(e -> {
            e.setIsTopName(YesNotEnum.getValueByCode(e.getIsTop()));
        });
        return devInfoList;
    }

    @Override
    public List<SysDevInfo> selectDevInfoList() {
        return sysDevInfoMapper.selectList(new QueryWrapper<>());
    }

    @Override
    public int updateDevInfo(SysDevInfo sysDevInfo) {
        UpdateWrapper<SysDevInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", sysDevInfo.getId());
        if (null != sysDevInfo.getSaveHis()) {
            SysDevCurrentData sysDevCurrentData = new SysDevCurrentData();
            sysDevCurrentData.setDeviceId(sysDevInfo.getDeviceId());
            sysDevCurrentData.setSaveHis(sysDevInfo.getSaveHis());
            sysDevCurrentDataMapper.updateById(sysDevCurrentData);
        }
        int i=sysDevInfoMapper.update(sysDevInfo, updateWrapper);
        updateSaveHisByCache(sysDevInfo.getDeviceId());
        return i;
    }

    @Override
    public void updateHasGroupCron(String devId, Boolean hasGroupCron) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("device_id", devId);
        SysDevInfo devInfo = new SysDevInfo();
        devInfo.setHasGroupCron(hasGroupCron);
        sysDevInfoMapper.update(devInfo, wrapper);
    }

    @Override
    public void updateSaveHisByCache(String devid) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("device_id", devid);
        wrapper.select("save_his");
        SysDevCurrentData currentData = sysDevCurrentDataMapper.selectOne(wrapper
        );
        if (currentData != null) {
            if (currentData.getSaveHis() == null){
                return;
            }
            Set cacheSaveHis = redisCache.getCacheSet(SoketEleKey.SAVE_HIS);
            if (cacheSaveHis == null) {
                cacheSaveHis = new HashSet();
            }
            if (currentData.getSaveHis() == 1) {
                cacheSaveHis.add(devid.toUpperCase());
                redisCache.setCacheSet(SoketEleKey.SAVE_HIS, cacheSaveHis);
            } else {
                redisCache.delCacheSet(SoketEleKey.SAVE_HIS, devid.toUpperCase());
            }
        }
    }

    @Override
    public void updataStatus(String devid) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("device_id", devid);
        SysDevInfo devInfo=new SysDevInfo();
        devInfo.setOnlineStatus(1);
         sysDevInfoMapper.update(devInfo,wrapper);
    }

    @Override
    public SysDevInfo getDeviceInfo(String devId) {
        QueryWrapper<SysDevInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_id", devId);
        return sysDevInfoMapper.selectOne(queryWrapper);
    }

    @Override
    public int insertDevInfo(PasingByteModel.Header header, DevLogin devLogin) {
        SysDevInfo sysDevInfo=new SysDevInfo();
        sysDevInfo.setActTime(new Date());
        sysDevInfo.setAddTime(System.currentTimeMillis());
        sysDevInfo.setDeviceId(header.getDvcId());
        sysDevInfo.setDevType(header.getDvcType());
        sysDevInfo.setRouterMac(devLogin.getRouterMac());
        sysDevInfo.setRemark("新增");
        sysDevInfo.setOnlineStatus(1);
        return sysDevInfoMapper.insert(sysDevInfo);
    }

    @Override
    public int updateVersion(String devId, String version) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("device_id",devId);
        SysDevInfo sysDevInfo=new SysDevInfo();
        sysDevInfo.setDevVersion(version);
        return sysDevInfoMapper.update(sysDevInfo,queryWrapper);
    }

    @Override
    public int bindName(String devId, String bindName) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("device_id",devId);
        SysDevInfo sysDevInfo=new SysDevInfo();
        sysDevInfo.setDevName(bindName);
        return sysDevInfoMapper.update(sysDevInfo,queryWrapper);
    }

    @Override
    public List<SysDevInfo> queryListByRq(GetWayInfoRq getWayInfoRq)  {

        return sysDevInfoMapper.queryByGetWay(getWayInfoRq);
    }

    /**
     * 获取在线设备mac地址的下拉框
     * @return
     */
    @Override
    public List<DevOnlineMacVO> getOnlineMac() {

        List<SysDevInfo> sysDevInfos = sysDevInfoMapper.getOnlineMac();

        List<DevOnlineMacVO> resList = sysDevInfos.stream().map(e -> {
            DevOnlineMacVO vo = new DevOnlineMacVO();
            vo.setId(e.getId());
            vo.setDevMac(e.getDeviceId());
            vo.setPollingMode(e.getPollingMode());
            return vo;
        }).collect(Collectors.toList());

        return resList;
    }

    @Override
    public AjaxResult changepollingMode(ModeChangeRq rq) {

        if(StringUtils.isBlank(rq.getDevMac())) {
            return  AjaxResult.error("没有在线设备！");
        }

        SysDevInfo devInfo = sysDevInfoMapper.selectOne(new QueryWrapper<SysDevInfo>().lambda()
                .eq(SysDevInfo::getDeviceId, rq.getDevMac()));
        if(devInfo == null) {
            return  AjaxResult.error("设备不存在");
        }

        SysDevCurrentData sysDevCurrentData = sysDevCurrentDataMapper.selectOne(new QueryWrapper<SysDevCurrentData>().lambda()
                .eq(SysDevCurrentData::getDeviceId, rq.getDevMac()));
        if(sysDevCurrentData == null) {
            return  AjaxResult.error("设备不存在");
        }
        Integer commandId = ChangeModeEnum.getCommandIdByCode(rq.getChangeCode());

        if(commandId > 0) {
            SysDevCommand sysDevCommand = devCommandMapper.selectById(commandId);
            if(sysDevCommand == null) {
                return AjaxResult.error("指令不存在");
            }
            // 更新设备的模式
            devInfo.setPollingMode(rq.getChangeCode());
            int row = sysDevInfoMapper.updateById(devInfo);
            if(row != 1) {
                return AjaxResult.error("更新失败");
            }
            // 命令数据处理
            String byteData = sysDevCommand.getByteData().replace("A1A1A1A1A1A1", rq.getDevMac());
            byteData = byteData.replace("A2", String.format("%02x", devInfo.getDevType()));
            // 发送命令
            boolean flag = SendMessage.sendMessage(ByteUtils.hexStrToBytes(byteData), devInfo.getDeviceId());
            if(flag) {
                return AjaxResult.success(flag);
            }
        }

        return AjaxResult.error("切换模式失败！");
    }

    @Override
    public int editIsTop(EditIsTopRQ rq) {
        // 校验
        if(StringUtils.isBlank(rq.getDevMac())) {
            throw new ServiceException("设备mac地址为空！");
        }

        String isTopValue = YesNotEnum.getValueByCode(rq.getIsTop());
        if(StringUtils.isBlank(isTopValue)) {
            throw new ServiceException("设置置顶错误：意外的值！");
        }

        if(rq.getIsTop().equalsIgnoreCase(YesNotEnum.Y.getCode())) {
            Integer count = sysDevInfoMapper.selectCount(new QueryWrapper<SysDevInfo>().lambda()
                    .eq(SysDevInfo::getIsTop, YesNotEnum.Y.getCode()));
            if(count >= 10) {
                throw new ServiceException("置顶失败：已经置顶的设备不能超过10个");
            }
        }

        // 匹配
        SysDevInfo devInfo = sysDevInfoMapper.selectOne(new QueryWrapper<SysDevInfo>().lambda()
                .eq(SysDevInfo::getDeviceId, rq.getDevMac()));
        if(devInfo == null) {
            throw new ServiceException("找不到对应的设备信息！");
        }
        // 更新
        int row = sysDevInfoMapper.update(null, new UpdateWrapper<SysDevInfo>().lambda()
                .eq(SysDevInfo::getDeviceId, rq.getDevMac())
                .set(SysDevInfo::getIsTop, rq.getIsTop()));

        return row;
    }
}
